﻿// Microsoft Public License (Ms-PL)
//
// This license governs use of the accompanying software. If you use the software, you accept this license.
// If you do not accept the license, do not use the software.
//
// 1. Definitions
//
// The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here 
// as under U.S. copyright law.
//
// A "contribution" is the original software, or any additions or changes to the software.
//
// A "contributor" is any person that distributes its contribution under this license.
//
// "Licensed patents" are a contributor's patent claims that read directly on its contribution.
//
// 2. Grant of Rights
//
// (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations 
// in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to 
// reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution 
// or any derivative works that you create.
//
// (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in 
// section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed 
// patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution 
// in the software or derivative works of the contribution in the software.
//
// 3. Conditions and Limitations
//
// (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or 
// trademarks.
//
// (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the 
// software, your patent license from such contributor to the software ends automatically.
//
// (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and 
// attribution notices that are present in the software.
//
// (D) If you distribute any portion of the software in source code form, you may do so only under this license 
// by including a complete copy of this license with your distribution. If you distribute any portion of the 
// software in compiled or object code form, you may only do so under a license that complies with this license.
//
// (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express 
// warranties, guarantees or conditions. You may have additional consumer rights under your local laws which 
// this license cannot change. To the extent permitted under your local laws, the contributors exclude the 
// implied warranties of merchantability, fitness for a particular purpose and non-infringement.

using System;
using System.Collections.Generic;
using System.Web.Services;
using StructuredSolutions.ShippingAgent;

namespace StructuredSolutions.ShippingAgent.Mock
{
    [WebService(Namespace = DefaultNamespace, Description = "Mock Shipping Agent by Structured Solutions.")]
    public class AgentService : AgentServiceBase
    {
        #region Abstract Method Implementation

        protected override List<OrderResult> GetNewOrdersFromStore(string lastOrderNumber, int maxCount)
        {
            return GetOrdersByRange(null, null, DateTime.MinValue, DateTime.MaxValue, lastOrderNumber, maxCount);
        }

        protected override OrderResult GetOrderFromStore(string orderId)
        {
            Order order = new Order();
            order.BillingAddress = new Address();
            order.BillingAddress.AddressId = "1";
            order.BillingAddress.City = "Portland";
            order.BillingAddress.Company = "ACME";
            order.BillingAddress.Country = "US";
            order.BillingAddress.Email = "test@acme.com";
            order.BillingAddress.FirstName = "Major";
            order.BillingAddress.LastName = "Domo";
            order.BillingAddress.Line1 = "6606 SE 34th";
            order.BillingAddress.PostalCode = "97202";
            order.BillingAddress.Region = "OR";
            order.Customer = new Customer();
            order.Customer.CustomerId = "1";
            order.Customer.Email = "customer@acme.com";
            order.Customer.FirstName = "First";
            order.Customer.LastName = "Last";
            order.Customer.UserName = "customer";
            order.Items = new List<Item>();
            order.Items.Add(new Item());
            order.Items[0].Code = "ABC";
            order.Items[0].ItemId = "1";
            order.Items[0].LineTotal = 2 * 9.99M;
            order.Items[0].Name = "Widget";
            order.Items[0].Price = 9.99M;
            order.Items[0].Quantity = 2;
            order.Items[0].Description = "Polished";
            order.OrderDate = DateTime.Today;
            order.OrderId = orderId;
            order.OrderNumber = "I" + (1000 + int.Parse(orderId));
            order.OrderStatus = "In Process";
            order.OrderTotal = 9.99M + 1.23M + 2;
            order.CustomerUrl = "http://localhost/mock/order/" + orderId;
            order.Charges = new NamedAmountList();
            order.Charges.Add(new NamedAmount("Taxes", 2));
            order.PaymentStatus = "Paid";
            order.ShippingCharge = 1.23M;
            order.ShippingStatus = "Unshipped";
            return new OrderResult {Success = true, Order = order};
        }

        protected override InventoryResult GetOrderInventoryFromStore(string orderId)
        {
            var result = new InventoryResult();
            result.Inventory = new List<ItemCount>();
            result.Inventory.Add(new ItemCount { Count = 10, ItemId = "1" });
            return result;
        }

        protected override List<OrderResult> GetOrdersByRangeFromStore(string startOrderNumber, string endOrderNumber, DateTime? startOrderDate, DateTime? endOrderDate, string lastOrderNumber, int maxCount)
        {
            // The mock implementation ignores the date criteria
            List<OrderResult> orders = new List<OrderResult>();

            int startOrderId = 0;
            int endOrderId = 100;
            if (!string.IsNullOrEmpty(startOrderNumber))
            {
                if (!int.TryParse(startOrderNumber.Substring(1), out startOrderId))
                    throw new ApplicationException(string.Format("Invalid starting order number '{0}'.", startOrderNumber));
                startOrderId = startOrderId - 1000;
            }
            if (!string.IsNullOrEmpty(lastOrderNumber))
            {
                int lastOrderId;
                if (!int.TryParse(lastOrderNumber.Substring(1), out lastOrderId))
                    throw new ApplicationException(string.Format("Invalid last order number '{0}'.", lastOrderNumber));
                startOrderId = lastOrderId - 999;
            }

            if (!string.IsNullOrEmpty(endOrderNumber))
            {
                if (!int.TryParse(endOrderNumber.Substring(1), out endOrderId))
                    throw new ApplicationException(string.Format("Invalid ending order number '{0}'.", endOrderNumber));
                endOrderId = endOrderId - 1000;
            }

            if (startOrderId < 0) throw new ApplicationException(string.Format("Invalid starting order number '{0}'.", startOrderId));
            if (endOrderId > 100) throw new ApplicationException(string.Format("Invalid ending order number '{0}'.", endOrderId));

            for (int orderId = startOrderId; orderId <= endOrderId; orderId++)
            {
                OrderResult orderResult = GetOrder(orderId.ToString());
                orderResult.Order.Packages = new List<PackageResult>();
                orderResult.Order.Packages.Add(GetPackage(orderId.ToString(), orderId.ToString()));
                orders.Add(orderResult);
                if (orders.Count == maxCount) break;
            }
            System.Threading.Thread.Sleep(1000);

            return orders;
        }

        protected override PackageResult GetPackageFromStore(string orderId, string packageId)
        {
            Package package = new Package();
            package.Charges = new NamedAmountList();
            package.Charges.Add(new NamedAmount("Handling", 1.23M));
            package.Charges.Add(new NamedAmount("Shipping Charge", 1.23M));
            package.Destination = new ShippingAddress();
            package.Destination.AddressId = "2";
            package.Destination.City = "Portland";
            package.Destination.Company = "ACME";
            package.Destination.Country = "US";
            package.Destination.Email = "test@acme.com";
            package.Destination.FirstName = "Shipping";
            package.Destination.LastName = "Department";
            package.Destination.Line1 = "123 Main St.";
            package.Destination.PostalCode = "97202";
            package.Destination.Region = "OR";
            package.Height = 6;
            package.Instructions = "This is a mock package.";
            package.Items = new List<Item>();
            package.Items.Add(new Item());
            package.Items[0].Code = "ABC";
            package.Items[0].ItemId = "1";
            package.Items[0].LineTotal = 2 * 9.99M;
            package.Items[0].Name = "Widget";
            package.Items[0].Price = 9.99M;
            package.Items[0].Quantity = 2;
            package.Items[0].Description = "Polished";
            package.Length = 6;
            package.MethodId = "1";
            package.MethodName = "Standard Shipping";
            package.OrderId = packageId;
            package.RateProviderId = "1";
            package.RateProviderName = "Mock";
            package.ShipDate = default(DateTime?);
            package.PackageId = packageId;
            package.CustomerUrl = "http://localhost/mock/package/" + packageId;
            package.Warehouse = new Address();
            package.Warehouse.AddressId = "3";
            package.Warehouse.City = "Seattle";
            package.Warehouse.Company = "ACME Distributing";
            package.Warehouse.Country = "US";
            package.Warehouse.FirstName = "Shipping";
            package.Warehouse.LastName = "Department";
            package.Warehouse.Line1 = "123 S. Main ST";
            package.Warehouse.PostalCode = "12356";
            package.Warehouse.Region = "WA";
            package.Weight = 5;
            package.Width = 6;
            return new PackageResult {Success = true, Package = package};
        }

        protected override List<TrackingProvider> GetTrackingProvidersFromStore()
        {
            List<TrackingProvider> providers = new List<TrackingProvider>();
            TrackingProvider provider = new TrackingProvider();
            provider.Name = "Mock";
            provider.TrackingProviderId = "1";
            providers.Add(provider);
            return providers;
        }

        protected override OrderResult UpdatePackageInStore(Update update)
        {
            return new OrderResult {Success = false, Message = "The Mock agent cannot update packages."};
        }

        #endregion
    }
}